package org.alerve.android.resourcebuilder;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import android.graphics.Movie;
import android.view.View;
import android.content.res.AssetFileDescriptor;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Resource {

	/**
	 * 
	 * The type of resources that can be fetched
	 * 
	 * @author pablisco
	 * 
	 */
	public enum ResourceType {
		/**
		 * Animations
		 * @see Resource#id()
		 */
		Anim, /* Animator, */
		/**
		 * Arrays, they should provide with the type of array necessary. The
		 * default is String.
		 * 
		 * @see Resource#arrayType()
		 * @see ArrayType
		 * @see Resource#id()
		 */
		Array,
		/**
		 * {@link View} attributes. Returns a {@link TypedArray} with the style
		 * attributes defined in a resource styleable.
		 * 
		 * TODO: need to work on this one, since it's most useful to load the
		 * attributes within the constructors of the view.
		 * 
		 * @see Resource#id()
		 * @see Resource#attr()
		 */
		Attr,
		/**
		 * Boolean values
		 * 
		 * @see Resource#id()
		 */
		Bool,
		/**
		 * Color resources. Should set {@link Resource#colorStateList()} as
		 * true if the needed resource is a {@link ColorStateList} instead of a
		 * {@link android.graphics.Color}
		 * @see Resource#colorStateList()
		 * 
		 * @see Resource#id()
		 */
		Color,
		/**
		 * Dimention resources. 
		 * 
		 * @see Resource#id()
		 */
		Dimen,
		/**
		 * Drawable resources (images, xml drawables, etc)
		 * 
		 * @see Resource#id()
		 */
		Drawable,
		/**
		 * Fractional resources
		 * 
		 * @see Resource#id()
		 */
		Fraction,
		/**
		 * View or layout identifiers
		 * 
		 * @see Resource#id()
		 */
		Id,
		/**
		 * Integer values
		 * 
		 * @see Resource#id()
		 */
		Integer,
		/**
		 * Interpolators for animations
		 * 
		 * @see Resource#id()
		 */
		Interpolator,
		/**
		 * Layout resources. No to be used with Layouts but rather to get the
		 * actual xml data
		 * 
		 * @see Resource#id()
		 */
		Layout, /* Menu, */
		/* MipMap, */
		/**
		 * Plural strings. It need to provide a quantity, default quantity is 1.
		 * 
		 * @see Resource#id()
		 */
		Plurals,
		/**
		 * Raw resources, such as movies. It
		 * 
		 * @needs rawType: The type of raw information required. Possible values
		 *        are
		 * @see RawType
		 * @see Resource#id()
		 */
		Raw,
		/**
		 * 
		 * @see Resource#id()
		 */
		String,
		// Style, Stylable,
		/**
		 * 
		 * @see Resource#id()
		 */
		Xml;
	}

	/**
	 * 
	 * Used with {@link Resource#arrayType()} when the
	 * {@link ResourceType#Array} is used with {@link Resource}
	 * 
	 * <ul>
	 * <li>{@link ArrayType#Integer}</li>
	 * <li>{@link ArrayType#Text}</li>
	 * <li>{@link ArrayType#String}</li>
	 * <li>{@link ArrayType#Typed}</li>
	 * </ul>
	 * 
	 * @example <code>
	 * @Resource(Array, ArrayType.Integer) <br/> int[] loadedResource; </code>
	 * 
	 */
	public enum ArrayType {
		/**
		 * Used to get an array of int values defined in a resource xml file.
		 * 
		 * @example <code>
		 * @Resource(Array, ArrayType.Integer) <br/> int[] loadedResource;
		 *                  </code>
		 * @see {@link ArrayType}
		 * 
		 */
		Integer,
		/**
		 * Used to get an array of {@link CharSequence} objects defined in a
		 * resource xml file
		 * 
		 * @example <code>
		 * @Resource(Array, ArrayType.Text) <br/> CharSequence[] loadedResource;
		 *                  </code>
		 * @see {@link ArrayType}
		 */
		Text,
		/**
		 * Used to get an array of {@link String} objects defined in a resource
		 * xml file
		 * 
		 * @example <code>
		 * @Resource(Array, ArrayType.String) <br/> String[] loadedResource;
		 *                  </code>
		 * @see {@link ArrayType}
		 */
		String
		// , Typed
		;
	}

	/**
	 * 
	 * Used with {@link Resource#arrayType()} when the {@link ResourceType#Raw}
	 * is used with {@link Resource}
	 * 
	 * <ul>
	 * <li>{@link RawType#InputStream}</li>
	 * <li>{@link RawType#Movie}</li>
	 * <li>{@link RawType#AssetFileDescriptor}</li>
	 * </ul>
	 * 
	 * @example
	 * 
	 *          <code>
	 * @Resource(Raw) <br/> {@link Movie Movie} movie; <br/>
	 * 
	 * @Resource(Raw, RawType.InputStream) <br/> {@link java.io.InputStream
	 *                InputStream} movie; <br/>
	 * 
	 *                </code>
	 * 
	 */
	public enum RawType {
		/**
		 * Used to get a {@link java.io.InputStream InputStream} instance to a
		 * file in the res folder.
		 */
		InputStream,
		/**
		 * Used to get a {@link Movie Movie} instance to a file in the res
		 * folder
		 */
		Movie,
		/**
		 * Used to get an {@link AssetFileDescriptor AssetFileDescriptor}
		 * instance referencing a file in the res folder.
		 */
		AssetFileDescriptor
	}

	/**
	 * Main argument sent to this annotation. Describes the type of resource to
	 * be used
	 */
	public ResourceType type() default ResourceType.Id;

	/**
	 * Used when a {@link Resource} is of type: {@link ResourceType#Array}
	 * 
	 * @return {@link ArrayType}
	 * @default {@link ArrayType#String}
	 */
	public ArrayType arrayType() default ArrayType.String;

	/**
	 * Used when a {@link Resource} is of type: {@link ResourceType#Raw}
	 * 
	 * @return {@link RawType}
	 * @default {@link RawType#Movie}
	 */
	public RawType rawType() default RawType.Movie;

	/**
	 * This property is used to find the required resource inside the targeted R
	 * class. If the value is not provided it will use either the provided
	 * {@link ResourceNameParser} or the default one. The default
	 * {@link ResourceNameParser} converts the camel case name of fields into a
	 * lower case with low lines. <br/>
	 * i.e.: <code>niceResource</code> will turn into <code>nice_resource</code>
	 * . <br/>
	 * 
	 * @return An int value as identifier.
	 */
	public int id() default Integer.MIN_VALUE;

	public String[] arguments() default {};

	/**
	 * Used to obtain the styles attributes. These are
	 * 
	 * @return
	 */
	public int[] attr() default {};

	/**
	 * @return true if the resource needed is of type {@link ColorStateList}
	 */
	public boolean colorStateList() default false;

	public int base() default 10;

	public int pbase() default 10;

	public int quatity() default 1;

}
